/**@file usercomm.c
 * @note 
 * @brief  测试代码
 * 
 * @author   luoxi
 * @date     20230106
 * @version  V1.0.0
 * 
 * @note ///Description here 
 * @note History:        
 * @note     <author>   <time>    <version >   <desc>
 * @note  
 * @warning  
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>

#include "log_level.h"
#include "usercomm.h"
#include "main.h"
#include "libfunc.h"
#include "fml_sqlite3.h"
#include "libfuncso.h"
#include "moduleB.h"
#include "fileoperation.h"

device_st pt_func;

typedef void (*sort_fn)(char *buff, unsigned len);



/* 我们调用其他模块的函数，并把回调函数传给其他模块，其他模块中的函数调用我们写的回调函数 */

static void deal_cmd(int cmd);        /* 处理用户命令 */
void rand_value(char *buff, int len); /* 生成 1 - 100之间的随机数 */
int func_value(int a);                /* 回调函数 函数功能 */


/**
 * @brief 用户通讯线程 处理用户下发的指令
 * 
 * @param[in]
 * @return
 */
void usercomm_thread_entry()
{

	/* 注册回调函数 注册回调函数的过程可以理解为让函数指针指向哪一个回调函数，同类型的函数都可以在这里注册 */
	/* 回调函数允许用户将一个方法的指针传到另外一个函数，以便该函数在处理类似事件时可以调用不同的函数 */
	if(0 != Register_callback(&pt_func))
	{
		log_error("Registe_callback error");
		return;
	}

	int option = 0;
	log_custom("************************************************");
	log_custom("1 递归函数测试!!!");
	log_custom("2 排序算法测试!!!");
	log_custom("3 计算字符串长度!!!");
	log_custom("4 crc校验测试!!!");
	log_custom("5 数据库测试!!!");
	log_custom("6 回调函数测试!!!");
	log_custom("7 文件读写测试!!!");
	log_custom("please input cmd:");
	
	FOREVER
	{
		scanf("%d", &option);    /* 获取输入函数 */
        //gets(&option);         /* 获取字符函数 ascll 码 */
        //puts(&option);
		log_custom("cmd option = %d", option);
	
		log_custom("please confirm your cmd(Y/N)");
		char a = getchar();
		if(a == 'Y')
		{
			log_custom("starting execute cmd");
            deal_cmd(option);
		}
		usleep(100*1000);
	}

}


/**
 * @brief 处理用户下发的指令
 * 
 * @param[in] 指令类型
 * @return
 */
static void deal_cmd(int cmd)
{
	switch (cmd)
	{
		case 1:
		{
			/*递归函数*/
	        int sum = recusion_digui(100);
	        log_custom("1-100 = %d", sum);
			break;
		}
        case 2:
		{
	        /* 排序算法 回调方法*/
            char sort_num[10] = {5, 2, 21, 23, 98, 12, 30, 35, 20, 10};
	        sort_fn sort_algorithm;
	        sort_algorithm = sort_maopao;
	        sort_algorithm(sort_num, 10);
	        break;  
		}
		case 3:
		{
			/* 计算字符串长度 */
			char str1[] = "helloworld";
			int len = str_len(str1);
			log_custom("len = %d", len);
			break;
		}
        case 4:
		{
	        /* crc校验 */
	        unsigned short result = 0x0;
	        char buff[10] = {0x01, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x1, 0x01};
	        result = crc16_get(buff, 10);
	        log_custom("result = %x", result);
			break;
		} 
		case 5: 
			/* 数据库初始化 */
			/* 数据库测试 */
			fml_sqlite3_init();
			break;
		case 6:
        {
			    /* 回调函数测试 这种是比较复杂的使用方法 尽量不要这么使用 */
	            ptrfunction myfu;
	            myfu = rand_value;
	            register_module(myfu);
	            my_function();  
			break;
        }
		case 7:
		    /* 文件读写测试 */ 
            read_file();
			break;

		case 8:
		{
		    //通过直接赋值调用也可以，但是就不能体现回调的优点了
	        pt_func.index = 1;
	        pt_func.function = func_value;
		    int ret = pt_func.function(cmd);
		    log_custom("ret = %d",ret);

	        //回调使用，调用后返回一个数
		    ret = my_test(cmd);
		    log_custom("ret = %d", ret);
			break;
		}

		default:
			break;
	}
}


/* 回调函数 函数功能 */
/**
 * @brief 生成 1 - 100之间的随机数
 * 
 * @param[in] 1 char *buff 数据保存区
 * @param[in] 2 int len 数据长度
 * @return    0 创建成功         -1 创建失败
 */
int func_value(int a)
{
	if(a>5)
	{
		a = rand() % 100;//生成一个随机数在0-100之间
		return a;
	}
	else
		return 0;
}


/**
 * @brief 生成 1 - 100之间的随机数
 * 
 * @param[in] 1 char *buff 数据保存区
 * @param[in] 2 int len 数据长度
 * @return    0 创建成功         -1 创建失败
 */
void rand_value(char *buff, int len)
{
	int i = 0;
	for(i = 0; i < len - 1; i++)
	{
		*buff = rand() % 100;
		buff++;
	}
}



